package org.generics;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;

public class TestGenerics {
    public static class Pair <T extends Number> {
        T first;
        T last;
        int sumOfList(List<? extends Integer> list) {
            int sum = 0;
            for (int i=0; i<list.size(); i++) {
                Integer n = list.get(i);
//                list.set(i, Integer.valueOf(20));
                sum = sum + n;
                list.set(i, null);
            }
            return sum;
        }
    }

    public static void test() {
        Class<Integer> clazz = Integer.class;
        try {
            Constructor<Integer> cons = clazz.getConstructor(int.class);
            Integer i = cons.newInstance(666);

            Pair<Float>[] ps = null;
//            Pair<Float>[] arr = new Pair<Float>[10];
            @SuppressWarnings("unchecked")
            Pair<Float>[] arrPair = (Pair<Float>[]) new Pair[10];

            String[] arr = asArray("one", "two", "three");
            System.out.println(Arrays.toString(arr));
            // ClassCastException:
            // class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.String;
            // ([Ljava.lang.Object; and [Ljava.lang.String; are in module java.base of loader 'bootstrap')
            String[] firstTwo = pickTwo("one", "two", "three");
            System.out.println(Arrays.toString(firstTwo));
        }catch (NoSuchMethodException exception) {

        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }


    }

    // unknown type cast to Object[]
    static <K> K[] pickTwo(K k1, K k2, K k3) {
        return asArray(k1, k2);
    }

    static <T> T[] asArray(T... objs) {
        return objs;
    }
}
